/*
 *  lyf - Conway's Game of Life in C++
 *  Copyright (C) 2006-2008 Antoine Kalmbach
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ***/
#include "board.h"
#include "grid.h"
#include "cell.h"
#include "ruleset.h"
#include <string>
#include <iostream>
#include <stdexcept>
#include <fstream>
#include <sstream>

namespace Life {

Board::Board(int width, int height) : xs(width), ys(height) 
{
    grid = new Grid(xs, ys);
}


void Board::load(const char *filename)
{
    std::ifstream ifs(filename);
    std::ostringstream buf;
    int w = 0, h = 0;

    // invalid file?
    if (!ifs.good())
        std::cout << "Couldn't open board file" << std::endl;

    // read width & height
    // using , as a delimiter now
    std::string header;
    getline(ifs, header);
    size_t delim_index = header.find_first_of(",");
    if (delim_index != std::string::npos)
    {
        std::string w_ = header.substr(0, delim_index);
        std::string h_ = header.substr(delim_index+1);
        w = atoi(w_.c_str());
        h = atoi(h_.c_str());
    }

    // can't load with empty dimensions
    if (h == 0 || w == 0)
        throw std::runtime_error("Error loading preset: empty dimensions");

    // read rest
    while (ifs.good())
    {
        std::string line;
        std::getline(ifs, line);
        buf << line;
    }

    board = buf.str();
    xs = w;
    ys = h;
    // parse the board
    if (board.size() == 0) 
        throw std::runtime_error("Can't parse, board string is empty");
    // create our grid
    // i.e. class wasn't initialized properly: Board b; b->grid would point to anything
    // as grid doesn't point to anything
    grid = new Grid(xs, ys);
    this->clear();
    grid->resize(xs, ys);
    std::string boardData = board;
    if ((int) boardData.size() != (xs * ys))
        throw std::runtime_error("Board data invalid"); 
    for (int h = 0; h <= ys; h++)
    {
        // read rows from the board, we know the row length so it's quite simple
        std::string row = boardData.substr(h*xs, xs);
        // row is incorrect, skip it
        if ((int) row.size() != xs)
            continue;
        for (int w = 0; w <= xs; w++)
           grid->set(w, h, (row[w] == '1') ? true : false); 
    }
}


}
